
//--xuezhen--

`include "defines.v"


module if_stage(
  input wire clk,
  input wire rst,

  input wire stall,
  input wire axi_stall,
  input wire jump_en,
  input wire [`REG_BUS]pc_dest,

  //from i_mem
  input wire [31:0] inst_i,

  //to i_mem  
  output wire [63 : 0]inst_addr,
  output reg         inst_ena,
  output wire [1:0] inst_size,

  //pass
  //output wire [31:0] inst_o,
  //output reg [`REG_BUS]pc

  
  output reg [`REG_BUS]pc_o,
  //output reg [31 : 0]inst
  output reg [31 : 0]inst_o
);

//parameter PC_START_RESET = `PC_START - 4;
parameter PC_START_RESET = `PC_START;

// fetch an instruction
reg [`REG_BUS]pc;
always@( posedge clk )
begin
  //pc <= {pc[63:2],2'b00};
  if( rst == 1'b1 )
  begin
    pc <= PC_START_RESET ;
  end
  else if ((axi_stall == 1'b1)||(inst_ena==1'b0)) begin
    pc <= pc;
  end
  else begin
    if (jump_en == 1'b1) begin
      pc <= pc_dest;
    end
    else begin
      if (stall == 1'b1) begin     //what if stall and flush become 1 at same time?
        pc <= pc;
      end
      else begin
        pc <= pc + 4;
      end
    end 
  end
end
assign inst_addr = pc;
//assign inst_addr = {pc[63:2],2'b00};
assign pc_o = pc;
//assign inst_ena  = ( rst == 1'b1 ) ? 0 : ((pc == PC_START_RESET)? 0:1);
//assign inst_ena  = ( rst == 1'b1 ) ? 0 : 1;
always@( posedge clk )
begin
  if( rst == 1'b1 )begin
    inst_ena <= 0 ;
  end
  else begin
    inst_ena <= 1;
  end
end
assign inst_size = `SIZE_W;
assign inst_o = inst_i;

/*
// Access memory
reg [63:0] rdata;
RAMHelper RAMHelper(
  .clk              (clk),
  .en               (1),
  .rIdx             ((pc - `PC_START) >> 3),   //right shift 3, equal to divide by 8
  .rdata            (rdata),
  .wIdx             (0),
  .wdata            (0),
  .wmask            (0),
  .wen              (0)
);
assign inst = pc[2] ? rdata[63 : 32] : rdata[31 : 0];   //read 64 from helper in one time
*/

endmodule
